package de.uhlesoluschns.opensearch.ui;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import android.app.Activity;
import android.content.Intent;
import android.content.res.Resources;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.KeyEvent;
import android.view.View;
import android.view.Window;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.TextView.OnEditorActionListener;
import de.uhlesoluschns.opensearch.R;

public class AddAdvanced extends Activity {
	
	private ListView siteList;
	private EditText searchSiteInput;
	private Button searchSiteGo;

	private FetcherTask fetcherTask; 
	
	private class FetcherTask extends AsyncTask<String, Exception, Uri> {
		
		@Override
		protected void onPreExecute() {
			setProgressBarIndeterminateVisibility(true);
		}
		
		@Override
		protected void onPostExecute(Uri result) {
			setProgressBarIndeterminateVisibility(false);
			searchSiteInput.setSelection(0, searchSiteInput.getText().length());
			fetcherTask = null;
			if(result != null) {
				startActivity(new Intent(Intent.ACTION_VIEW, result, AddAdvanced.this, SearchProvider.class));
			}
		}
		
		@Override
		protected void onProgressUpdate(Exception... values) {
			Toast.makeText(AddAdvanced.this, values[0].getLocalizedMessage(), Toast.LENGTH_LONG).show();
		}
		
		@Override
		protected Uri doInBackground(String... params) {
			String urlString = params[0];
			InputStream is = null;
			try {
				URL url = new URL(urlString);
				
				HttpURLConnection connection = (HttpURLConnection) url.openConnection();
				is = connection.getInputStream();
				
				InputStreamReader reader = new InputStreamReader(is);

				StringBuilder content = new StringBuilder();
				
				char [] buf = new char[1024];
				int read = -1;
				while((read = reader.read(buf)) > 0) {
					content.append(buf, 0, read);
				}
				List<Properties> providers = new ArrayList<Properties>();
				Matcher tagMatcher = Pattern.compile("<link\\s*rel=\"search\"(.*)\\/{0,1}>").matcher(content);
				while(tagMatcher.find()) {
					String tagProperties = tagMatcher.group(1);
					if(TextUtils.isEmpty(tagProperties)) {
						continue;
					}
					
					Matcher propertiesMatcher = Pattern.compile("([\\S]*)=\"([^\"]*)\"").matcher(tagProperties);
					Properties properties = new Properties();
					while(propertiesMatcher.find()) {
						properties.setProperty(propertiesMatcher.group(1), propertiesMatcher.group(2));
					}
					if("application/opensearchdescription+xml".equals(properties.getProperty("type"))) {
						providers.add(properties);
					}
				}
				
				/*if(providers.isEmpty()) {
					Toast.makeText(AddAdvanced.this, R.string.ui_add_advanced_search_site_nothing_found, Toast.LENGTH_LONG).show();
				}*/
				String providerUrl = null;
				if(providers.size() == 1) {
					Properties provider = providers.get(0);
					//TODO handle relative after redirect!
					providerUrl = provider.getProperty("href");
					if(!providerUrl.startsWith("http")) {
						providerUrl = urlString + providerUrl;
					}
				} else {
					throw new IllegalArgumentException(getResources().getString(R.string.ui_add_advanced_search_site_nothing_found));
				}
				return Uri.parse(providerUrl);
			} catch (Exception e) {
				publishProgress(e);
				return null;
			} finally {
				try {
					is.close();
				} catch (IOException e) {}
			}
		}
	};
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
		
		setContentView(R.layout.add_advanced);

		Resources resources = getResources();
		siteList = (ListView) findViewById(R.id.search_linklist);
		siteList.setAdapter(new ArrayAdapter<String>(this, 
				R.layout.add_advanced_url, 
				resources.getStringArray(R.array.external_provider_sites)));
		siteList.setDivider(null);
		siteList.setDividerHeight(5);
		siteList.setOnItemClickListener(new OnItemClickListener() {
			public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
				Intent intent = new Intent(AddAdvanced.this, Browser.class);
				intent.setData(Uri.parse(((TextView)view).getText().toString()));
				startActivity(intent);
			}
		});
		
		searchSiteInput = (EditText) findViewById(R.id.search_site_input);
		searchSiteInput.setOnEditorActionListener(new OnEditorActionListener() {
			@Override
			public boolean onEditorAction(TextView v, int actionId,
					KeyEvent event) {
				searchSiteForProvider();
				return true;
			}
		});
		searchSiteGo = (Button) findViewById(R.id.search_site_go);
		searchSiteGo.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				searchSiteForProvider();
			}
		});
	}
	
	private void searchSiteForProvider() {
		if(fetcherTask != null) {
			return;
		}
		String urlString = null;
		urlString = searchSiteInput.getText().toString();
		
		if(!TextUtils.isEmpty(urlString)) {
			if(!urlString.startsWith("http")) {
				urlString = "http://" + urlString;
			}
		}
		fetcherTask = new FetcherTask();
		fetcherTask.execute(urlString);
	}
	
}
